(function($){
	var _cache={},$$ = function(treeId){
		var set = function(parms){
			if(parms){
				if(!_cache[treeId]){
					_cache[treeId] = parms;
				}else{
					for(var i in parms){
						if(parms[i]!=undefined && parms[i]!=null ){
							_cache[treeId][i]=parms[i];
						}
					}
				}
			}
		}
		var get = function(key,value){
			if(!_cache[treeId]){
				_cache[treeId]={};
			}
			if(value){
				_cache[treeId][key] = value;
			}else if(key){
				return _cache[treeId][key];
			}else{
				return _cache[treeId];
			}
		}
		return {
			load:function(parms){
				set(parms);
				return this;
			},
			data:function(key,value){
				return get(key,value);
			}
		}
	};
	var _tool = {
		getEvent : function() {
			var appName = navigator.appName;
			var not_IE_Opera = appName != "Microsoft Internet Explorer"
					&& appName != "Opera";
			if (not_IE_Opera) {
				func = this.getEvent.caller;
				var deep = 0;
				var max = 10;
				while (func != null && deep<max) {
					var $ = func.arguments[0];
					if ($ && ($ + "").indexOf("Event") >= 0)
						return $;
					func = func.caller;
					deep++;
				}
				return null;
			}
			return event;
		},
		getEl : function() {
			var event = this.getEvent();
			if(!event) return null;
			return event.srcElement || event.target;
		},
		str2Arr: function(str){
			//sdf,sdf---> [{id:'sdf'},{id:'sdf'}]
			var result = [];
			if(!str || str=='')return result;
			$.each(str.split(','),function(i,v){
				if(v){
					result.push({id:v.trim()});
				}
			});
			return result;
		},
		arrPop:function(arr,id){
			var result = [];
			if(!arr)return result;
			for(var i in arr){
				var v = arr[i];
				if(v.id && id!=v.id){
					result.push(v);
				}
			}
			return result;
		},
		arr2str: function(arr){
			//[{id:'sdf',name:'11'},{id:'sdf',name:'22'}] ---> sdf,sdf
			var result = "";
			if(!arr)return result;
			for(var i in arr){
				var v = arr[i];
				if(v.id){
					result += v.id;
					result += ',';
				}
			}
			result = result.replace(/,$/g,'');
			return result;
		},
		arr2strOfName: function(arr){
			//[{id:'sdf',name:'11'},{id:'sdf',name:'22'}] ---> sdf,sdf
			var result = "";
			if(!arr)return result;
			for(var i in arr){
				var v = arr[i];
				if(v.id){
					result += v.name;
					result += ',';
				}
			}
			result = result.replace(/,$/g,'');
			return result;
		},
		getSetting:function(set){
			var result ={};
			for(var i in set){
				if(set[i]!=undefined && set[i]!=null 
						//&& !(set[i] instanceof HTMLElement) 
						&& !(set[i] instanceof jQuery) ){
					result[i]=set[i];
				}
			}
			return result;
		},
		extend:function(){
			var src, copyIsArray, copy, name, options, clone,
				target = arguments[0] || {},
				i = 1,
				length = arguments.length,
				deep = false;
			// Handle a deep copy situation
			if ( typeof target === "boolean" ) {
				deep = target;
				target = arguments[1] || {};
				// skip the boolean and the target
				i = 2;
			}
			// Handle case when target is a string or something (possible in deep copy)
			if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
				target = {};
			}
			// extend jQuery itself if only one argument is passed
			if ( length === i ) {
				target = this;
				--i;
			}
			for ( ; i < length; i++ ) {
				// Only deal with non-null/undefined values
				if ( (options = arguments[ i ]) != null ) {
					// Extend the base object
					for ( name in options ) {
						src = target[ name ];
						copy = options[ name ];
	
						// Prevent never-ending loop
						if ( target === copy ) {
							continue;
						}
						// Recurse if we're merging plain objects or arrays
						if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
							if ( copyIsArray ) {
								copyIsArray = false;
								clone = src && jQuery.isArray(src) ? src : [];
								target[ name ] = copy;
							} else {
								clone = src && jQuery.isPlainObject(src) ? src : {};
								target[ name ] = _tool.extend(true, deep, clone, copy );
							}
							// Never move original objects, clone them
						// Don't bring in undefined values
						} else if ( copy!=undefined && copy!=null ) {
							target[ name ] = copy;
						}
					}
				}
			}
			// Return the modified object
			return target;
		},
		isTreeEmpty:function(treeId){
			var zTree = $.fn.zTree.getZTreeObj(treeId);
			if(zTree && zTree.setting && zTree.setting.treeObj && zTree.setting.treeObj.children().length!=0){
				return false;
			}
			return true;
		}
	};
	
	
	
	using('tree',function(){
		$.fn.zTree.init_input = function($tar,setting,nodes){
			var treeId = $tar.attr('id');
			var $value = $$(treeId).data('value');
			var $form=$value.parents('form'),
				$menuBtn = $value.siblings('#menuBtn');
			$value.data.showMenu = function(){
				var $value = $(_tool.getEl()),$menuContent=$value.siblings('#menuContent');
				$menuContent.slideDown("fast");
			}
			$value.parent().on('mousedown','div,input,i,a',function(){
				$(_tool.getEl()).data.showMenu();
				return false;
			})
			$form.unbind('mousedown').bind('mousedown',function(){
				$('.ztree').each(function(){
					$(this).parent().fadeOut("fast");
				});
			})
			$value.click(function(){
				$(_tool.getEl()).data.showMenu();
			});
			$menuBtn.click(function(){
				$(_tool.getEl()).data.showMenu();
			});
				
			return $.fn.zTree.init($tar,setting,nodes||[]);
		}
	});

	var constant = {
		chkType:function(type){
			switch (type+'') {
			case '1':
				return {
					enable: true,
					chkStyle: "radio",
					radioType: "all"
				}
			case '2':
				return {
					enable: true,
					chkStyle: "checkbox",
					radioType: "all"
				}
			default:
				return {
					enable: false
				}
			}
		},
		async: function(treeUrl,checkNodes){
			if(checkNodes instanceof Array){
				checkNodes = _tool.arr2str(checkNodes);
			}
			return {
				enable: true,
				url:treeUrl,
				autoParam:["id=parentId"],
				otherParam: ["checkIds",checkNodes],
				type:"post"
			}
		},
		OrgTree: {
			id:'OrgTree',
			title:'请选择部门',
			treeUrl:'getOrgTreeJson.action',
			dialogUrl:'listtree.jsp',
			getCheckedNodes:null,//getCheckedLeaf
			setting:{
				check:{
					chkboxType: { "Y" : "", "N" : "" }
				}
			}
		},
		UserTree: {
			id:'UserTree',
			title:'请选择用户',
			treeUrl:'getUserTreeJson.action',
			dialogUrl:'listtree.jsp',
			getCheckedNodes:getCheckedLeaf
		},
		PostTree: {
			id:'PostTree',
			title:'请选择岗位',
			treeUrl:'getPostTreeJson.action',
			dialogUrl:'listtree.jsp',
			getCheckedNodes:getCheckedLeaf
		}
	};
	
	var _settings = {
		chkType:null,//树节点类型：0无，1单选，2多选
		checkNodes:null,//选中节点: [{id:'asdfa',name:'最高机构'}]，最终选中节点的判断优先级：inputId，checkNodes
		inputId:null,//隐藏域的id，用来存放选中节点的id(以,隔开)，注：与button在html结构上为兄弟
		spanId:null,//同上，用来存放选中节点的名称
		setting:null,//ztree的配置: {}
		isRead:false,//是否只读
		
		treeType:null,//input menu dialog
		id:'',
		title:'请选择',
		treeUrl:null,//树url
		dialogUrl:null,//弹出框url
		getCheckedNodes:null
	};


var Tree = function(el,treeConstant,parms){
	if(!el || el==window){return;}
	var settings = {},parm = parms[0];
	//参数初始化
	_tool.extend(true,settings,_settings);
	//树的默认设置
	if(treeConstant){
		_tool.extend(true,settings,treeConstant);
	}
	//外部参数初始化
	_tool.extend(true,settings,parm);
	
	var $el = $(el);
	var _tree =  {};
	if(!settings.treeType){
		if($el.is('input[type=text]')){
			_tree = _Tree.input;
		}else if($el.is('ul')){
			_tree = _Tree.menu;
		}else if($el.is('[type=button]')){
			isReload = true;
			_tree = _Tree.dialog;
		}else{
			isReload = true;
			_tree = _Tree.dialog;
		}
	}else{
		_tree = _Tree[settings.treeType];
	}
	//ztree.js是否加载
	if(!($ && $.fn.zTree)){
		return;
	}
	settings.target = $el;
	return _tree.init(settings);
};


var _Tree = {
		input:{
			tree:function($el){
				return $el.siblings('#menuContent').find('.ztree');
			},
		 	treeHtml:function(treeId){
				return '<i style="cursor:pointer;margin-left: -20px;margin-top: 5px; margin-right: 9px;margin-left: -25px\0;background-position:-1px -1px\0 ;background-repeat:no-repeat\0 ;margin-right:0px\0;background-image:url(cssui/plugins/bootstrap/img/input-closeicon.png)\0;" for="deptName" title="清空" class="icon-remove" ></i>'
				+'<a id="menuBtn" href="#"></a>'
				+'<div id="menuContent" class="menuContent" style="position: absolute; z-index: 99999; display: none;">'
					+'<ul id="'+treeId+'" class="ztree" style="margin-top:0; width:150px; height: 260px;background:white;border:#e5e7ee solid 1px;overflow:auto;"></ul>'
				+'</div>';
			},
			reset: function(){
				var that = _tool.getEl();
				if(!that){return;}
				//1.clear input value
				$(that).parent().find('input').each(function(){
					$(this).val("");
				});
				//2.clear tree
				if( !($ && $.fn.zTree) ){return;}
				var rtree = $.fn.zTree.getZTreeObj($(that).parent().find('.ztree').attr('id'));
				if(rtree){
					//rtree.cancelSelectedNode();
				    var nodes = rtree.getCheckedNodes(true);
				    for (var i=0, l=nodes.length; i<l; i++) {
						rtree.checkNode(nodes[i], false, true, true);
					}
				}
			},
			onCheck: function (e, treeId, treeNode) {
				var	getCheckedNodes = $$(treeId).data('getCheckedNodes'),
					v = "",
					v1 = "",
					nodes=[];
				var checkNodes = [];
				if(getCheckedNodes && typeof(getCheckedNodes)==='function'){
					nodes = getCheckedNodes(treeId);
				}else{
					var zTree = $.fn.zTree.getZTreeObj(treeId);
					nodes = zTree.getCheckedNodes(true);
				}
				for (var i=0, l=nodes.length; i<l; i++) {
					if(nodes[i].checked && nodes[i].use!=false){
						v += nodes[i].id + ",";
						v1 += nodes[i].name + ",";
						var checkNode = {id:nodes[i].id,name:nodes[i].name};
						checkNodes.push(checkNode);
					}
				}
				if (v.length > 0 ) v = v.substring(0, v.length-1);
				if (v1.length > 0 ) v1 = v1.substring(0, v1.length-1);
				var $key = $$(treeId).data('key');
				var $value = $$(treeId).data('value');
				$key.val(v);
				$value.val(v1);
				$value.trigger('reset');
				$$(treeId).data('checkNodes',checkNodes);
				//同步onclick的数据
				var parms = ($$(treeId).data('value').attr('onclick')||'').match(/\({.+}\)/);
				if(parms){
					if(parms instanceof Array )parms = parms[0];
					var parmsObj = eval(parms);
					parmsObj.checkNodes = checkNodes;
					$$(treeId).data('value').attr('onclick',$$(treeId).data('value').attr('onclick').replace(parms,'('+JSON.stringify(_tool.getSetting(parmsObj||{}))+')'));
				}
				$(this).parent().remove();
			},
			init:function(parms){
				var $tree,$key,$value = parms.target,
					chkType=parms.chkType,isRead=parms.isRead,
					_tree=this;
				//标准化key和value两个input的id
				//value id:dept
				//key id:deptId
				var id = $value.attr('id');
				if(!id){
					id = new Date().getTime();
					$value.attr('id',id);
				}
				$tree = _tree.tree($value);
				if($tree.length==0){
					//插入key、清空按钮、下拉菜单
					var $new = $(_tree.treeHtml('ztree_'+new Date().getTime()));
					$value.after($new);
					$tree = _tree.tree($value);
					//给清空按钮加载事件
					$value.siblings('.icon-remove').click(function(){
						_tree.reset();
					});
				}
				if(!_tool.isTreeEmpty($tree.attr('id'))){
					return $$($tree.attr('id')).data();
				}
				$key = $value.siblings('#'+(parms.inputId||id+'Id'));
				if($key.length==0){
					$key = $('<input type="hidden" name="'+(parms.inputId||id+'Id')+'" id="'+(parms.inputId||id+'Id')+'" >');
					$value.parent().append($key);
				}
				//修正value的值、属性和样式
				$value.attr('placeholder',$value.attr('placeholder')||parms.title);
				$value.attr('readonly','readonly').css('cursor','pointer');
				//修正选中节点
				var checkNodes = [];
				if($key.val()){
					$.each($$($tree.attr('id')).data('checkNodes')||[],function(i,v){
						if($key.val().indexOf(v.id)!=-1){
							checkNodes.push(v);
						}
					});
				}else{
					checkNodes = parms.checkNodes;
				}
				parms.checkNodes = checkNodes||[];
				$key.val(_tool.arr2str(checkNodes)||'');
				$value.val(_tool.arr2strOfName(checkNodes)||'');
				
				if(!isRead){
					//给button加载事件
					$value.attr('onclick',parms.id+'('+JSON.stringify(_tool.getSetting(parms||{}))+')')
				}
				
				//内部自定义
				var ztree_setting = {
					input: {
						window:window,
						menuBtn: $value.siblings('#menuBtn'),
						menuContent: $value.siblings('#menuContent'),
						form: $value.parents('form'),
						key: $key,
						value: $value,
						tree:$value.siblings('#menuContent').find('.ztree')
					},
					data: {
						simpleData: {
							enable: true
						}
					},
					async:constant.async(parms.treeUrl,_tool.arr2str(checkNodes)),
					check:constant.chkType(chkType),
					callback: {
						onCheck: _tree.onCheck
					}
				};
				_tool.extend(true,ztree_setting, parms.setting||{});
				parms.setting = ztree_setting;
				//保存参数
				$$($tree.attr('id')).load(parms).load({
					'tree':$tree,
					'key':$key,
					'value':$value
				});
				$.fn.zTree.init_input($tree,ztree_setting);
				return $$($tree.attr('id')).data();
			}
		},
		menu:{
			init:function(parms){
				var $tree = parms.target,
				chkType=parms.chkType,isRead=parms.isRead,checkNodes=parms.checkNodes,
				_tree=this;
				if(!_tool.isTreeEmpty($tree.attr('id'))){
					return $$($tree.attr('id')).data();
				}
				//内部自定义
				var ztree_setting = {
					data: {
						simpleData: {
							enable: true
						}
					},
					async:constant.async(parms.treeUrl,_tool.arr2str(checkNodes)),
					check:constant.chkType(chkType),
					callback: {
						onCheck: _tree.onCheck,
						onNodeCreated: _tree.onNodeCreated
					}
				};
				_tool.extend(true,ztree_setting, parms.setting||{});
				parms.setting = ztree_setting;
				//保存参数
				$$($tree.attr('id')).load(parms).load({
					'tree':$tree,
				});
				$.fn.zTree.init($tree,ztree_setting);
				return $$($tree.attr('id')).data();
			}
		},
		dialog:{
			save:function(id,nodes){
				var getSpan = function(nodeId,nodeName,isRead){
					var html = '<span rel="'+nodeId+'" title="'+nodeName+'">'+nodeName;
					if(!isRead){
						html += '<a href="javascript:;" title="删除"><img style="margin-bottom:-3px" src="portal/images/icon/btn_del.png"></a>'
					}	  
					html += '</span>';
					var $html = $(html);
					$html.find('a').click(function(){
						//同步input的数据
						$key.val($key.val().replace(nodeId+',','').replace(nodeId,'').replace(/,$/,'').replace(/^,/,''));
						var checkNodes = _tool.arrPop($$(id).data('checkNodes')||[],nodeId);
						//同步缓存checkNodes的数据
						$$(id).data('checkNodes',checkNodes);
						//同步onclick的数据
						var parms = ($$(id).data('button').attr('onclick')||'').match(/\({.+}\)/);
						if(parms){
							if(parms instanceof Array )parms = parms[0];
							var parmsObj = eval(parms);
							parmsObj.checkNodes = checkNodes;
							$$(id).data('button').attr('onclick',$$(id).data('button').attr('onclick').replace(parms,'('+JSON.stringify(_tool.getSetting(parmsObj||{}))+')'));
						}
						$(this).parent().remove();
					});
					return $html;
				}
				var $key = $$(id).data('input');
				var $span = $$(id).data('span');
				var isRead = $$(id).data('isRead');
				$key.val('');
				$span.empty();
				var keys = '',values = '';
				if(nodes){
					for(var i=0;i<nodes.length;i++){
						var node = nodes[i];
						keys += node.id;
						values += node.name;
						if(node.name){
							$span.append(getSpan(node.id,node.name,isRead));
						}
						if(i!=nodes.length-1){
							keys += ',';
							values += ',';
						}
					}
				}
				$key.val(keys);
				$$(id).data('checkNodes',nodes);
				return true;
			},
			init:function(parms){
				var $span,$key,$button = parms.target,
					chkType=parms.chkType,isRead=parms.isRead,
					_tree=this;
				//是否初次加载，不弹出框
				var isInit = false;
				//从对象加载isInit为true
				if(!$button.attr('onclick') || $button.attr('onclick').indexOf(parms.id)==-1){
					isInit = true;
				}
				var id = $button.attr('id');
				if(!id){
					id = new Date().getTime();
					$button.attr('id',id);
				}
				
				
				//插入key、span区域
				if(!parms.inputId)parms.inputId=id+'Input';
				if(!parms.spanId)parms.spanId=id+'Span';
				$key = $button.siblings('#'+parms.inputId);
				if($key.length==0){
					$key = $('<input type="hidden" name="'+parms.inputId+'" id="'+parms.inputId+'" >');
					$button.after($key);
				}
				$span = $button.siblings('#'+parms.spanId);
				if($span.length==0){
					$span = $('<span name="'+parms.spanId+'" id="'+parms.spanId+'" ></span>');
					$button.after($span);
					
				}
				
				//修正选中节点
				var checkNodes = [];
				if($key.val()){
					$.each($$($button.attr('id')).data('checkNodes')||[],function(i,v){
						if($key.val().indexOf(v.id)!=-1){
							checkNodes.push(v);
						}
					});
				}else{
					checkNodes = parms.checkNodes;
				}
				parms.checkNodes = checkNodes||[];
				$key.val(_tool.arr2str(checkNodes)||'');
				
				//是否只读
				if(!isRead){
					//给button加载事件
					$button.attr('onclick',parms.id+'('+JSON.stringify(_tool.getSetting(parms||{}))+')');
				}
				
				//内部自定义
				var ztree_setting = {
					async:constant.async(parms.treeUrl,$key.val()||_tool.arr2str(checkNodes)),
					check:constant.chkType(chkType)
				};
				_tool.extend(true,ztree_setting, parms.setting||{});
				parms.setting = ztree_setting;
				//保存参数
				$$($button.attr('id')).load(parms).load({
					'span':$span,
					'input':$key,
					'button':$button,
					'set':function(nodes){_tree.save($button.attr('id'),nodes);}
				});
				
				if(isInit || isRead){
					_tree.save($button.attr('id'),checkNodes||[]);
				}else{
					var a={
							id:$button.attr('id')||new Date().getTime(),
							title:parms.title,
							parent:$.dialog.focus||null,
							lock:true,
							resize: false,
							max:false,
							min:false,
							padding: 0,
							data:{
									settings:$$($button.attr('id')).data(),
									save:function(nodes){
										return _tree.save($button.attr('id'),nodes);
									}
							}
					}
					var api = $.dialog(a);
					$.ajax({
						url:'acl/common/tree/'+(parms.dialogUrl||'listtree.jsp'),
						success:function(data){
							api.content(data);
							$(api.DOM.content[0]).initUI();
						},
						cache:false
					});
				}
				
				return $$($button.attr('id')).data();
			}

		}
	};

/**
 * 机构树
 * {}  _settings
 * @return
 */
var OrgTree = function(){
	var el = _tool.getEl(),el = el==null?this:el;
	var parms = [].slice.call(arguments);
	return Tree(el,constant.OrgTree, parms);
};
$.prototype.OrgTree = window.OrgTree = OrgTree;
/**
 * 用户树
 * {}  _settings
 * @return
 */
var UserTree = function(){
	var el = _tool.getEl(),el = el==null?this:el;
	var parms = [].slice.call(arguments);
	return Tree(el,constant.UserTree,parms);
};
$.prototype.UserTree = window.UserTree = UserTree;
/**
 * 岗位树
 * {}  _settings
 * @return
 */
var PostTree = function(){
	var el = _tool.getEl(),el = el==null?this:el;
	var parms = [].slice.call(arguments);
	return Tree(el,constant.PostTree,parms);
};
$.prototype.PostTree = window.PostTree = PostTree;

/**
 * 对于树的扩展
 */
/**
 * 执行人树
 * {}  _settings
 * @return
 */
constant.PerformerTree = {
	id:'PerformerTree',
	title:'请选择用户',
	dialogUrl:'querytree.jsp',
	getCheckedNodes:null
};
var PerformerTree = function(){
	var el = _tool.getEl(),el = el==null?this:el;
	var parms = [].slice.call(arguments);
	return Tree(el,constant.PerformerTree,parms);
};
$.prototype.PerformerTree = window.PerformerTree = PerformerTree;

})(jQuery);
